package com.orhon.smartcampus.modules.student.mutation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.orhon.smartcampus.auth.JwtUtils;
import com.orhon.smartcampus.basicComponents.Result;
import com.orhon.smartcampus.modules.base.dao.SchoolsDao;
import com.orhon.smartcampus.modules.base.entity.Schools;
import com.orhon.smartcampus.modules.student.dao.ArrivesDao;
import com.orhon.smartcampus.modules.student.dao.LearninfoDao;
import com.orhon.smartcampus.modules.student.dao.SInformationDao;
import com.orhon.smartcampus.modules.student.entity.Arrives;
import com.orhon.smartcampus.modules.student.entity.Learninfo;
import com.orhon.smartcampus.modules.student.entity.SInformation;
import com.orhon.smartcampus.modules.student.gqlInputModel.GQLStudentInput;
import com.orhon.smartcampus.modules.student.inputMapper.StudentInputMapper;
import com.orhon.smartcampus.modules.user.dao.TokenService;
import com.orhon.smartcampus.modules.user.dao.UsersDao;
import com.orhon.smartcampus.modules.user.entity.Users;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

@Component
public class AddStudentMutation implements DataFetcher {


    @Autowired
    SInformationDao sInformationDao;

    @Autowired
    UsersDao usersDao;

    @Autowired
    SchoolsDao schoolsDao;

    @Autowired
    ArrivesDao arrivesDao;

    @Autowired
    LearninfoDao learninfoDao;


    @Autowired
    TokenService tokenService;
    /**
     * 学生新增/修改接口
     * editor : ths
     */
    @Override
    @Transactional(readOnly = false)
    public Object get(DataFetchingEnvironment environment) throws Exception {

        String token = tokenService.getSystemToken();
        Long schoolId = JwtUtils.getSchoolId(token);
        GQLStudentInput input = StudentInputMapper.MAPPER.mapInput(environment.getArgument("inputData"));
        SInformation sInformation = null;
        if (input.getId() != null){
            sInformation = sInformationDao.get(SInformation.class, input.getId());
            sInformation.setUpdated_at(new Date());
            sInformation = this.dataInjection(sInformation, input ,null);
            try {
                sInformationDao.saveOrUpdate(sInformation);
            } catch (Exception e) {
                return Result.error(500, "" + e);
            }
            List<SInformation> list = new ArrayList<>();
            list.add(sInformation);
            return Result.ok().put("data",list);
        } else {
            Long studentId;
            Long userId;
            /**
             * 查找该学生是否已有学生基础信息
             */
            DetachedCriteria s_criteria = DetachedCriteria.forClass(SInformation.class);
            s_criteria.add(Restrictions.isNull("deleted_at"));
            s_criteria.add(Restrictions.eq("idcard", input.getIdcard()));
            List<SInformation> sInformations = (List<SInformation>) sInformationDao.findByCriteria(s_criteria);
            SInformation old_sInformation = sInformations.size()>0?sInformations.get(0):null;
            if (old_sInformation != null) {
                sInformation = old_sInformation;
                sInformation.setUpdated_at(new Date());
                sInformation = this.dataInjection(sInformation, input ,null);
                Users user = sInformation.getUser();
                userId = user.getId();
                studentId = sInformation.getId();
                try {
                    sInformationDao.saveOrUpdate(sInformation);
                } catch (Exception e) {
                    return Result.error(500, "" + e);
                }
            } else {
                /**
                 * 是否存在基础用户信息
                 */
                DetachedCriteria u_criteria = DetachedCriteria.forClass(Users.class);
                u_criteria.add(Restrictions.isNull("deleted_at"));
                u_criteria.add(Restrictions.eq("idCard", input.getIdcard()));
                List<Users> users = (List<Users>) usersDao.findByCriteria(u_criteria);
                Users old_user = users.size()>0?users.get(0):null;
                if (old_user != null) {
                    userId = old_user.getId();
                } else {
                    Users user = new Users();
                    if(input.getIdcard() != null){

                        user.setIdCard(input.getIdcard());
                        user.setUsername(input.getIdcard());
                    }
                    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
                    String encode = bCryptPasswordEncoder.encode("123456");
                    user.setPassword(encode);
                    if(input.getEmail() != null){

                        user.setEmail(input.getEmail());
                    }
                    user.setUser_type("student");
                    if(input.getTel_number() != null){

                        user.setMobile(input.getTel_number());
                    }
                    Schools schools = schoolsDao.get(Schools.class , schoolId);
                    user.setSchool(schools);
                    Users new_user;
                    try {
                        new_user = usersDao.save(user);
                    } catch (Exception e) {
                        return Result.error(500, "" + e);
                    }
                    userId = new_user.getId();
                }
                sInformation = new SInformation();
                sInformation.setCreated_at(new Date());
                sInformation = this.dataInjection(sInformation, input ,userId);
                SInformation new_sInformation;
                try {
                    new_sInformation = sInformationDao.add(sInformation);
                } catch (Exception e) {
                    return Result.error(500, "" + e);
                }
                studentId = new_sInformation.getId();
            }
            Learninfo learninfo = new Learninfo();
            learninfo.setStudentSInformationByStudentId(sInformationDao.get(SInformation.class, studentId));
            learninfo.setBaseSchoolsBySchoolId(schoolsDao.get(Schools.class, schoolId));
            learninfo.setUserUsersByUserId(usersDao.get(Users.class, userId));
            learninfo.setStudentArrivesByArriveId(arrivesDao.get(Arrives.class, input.getArrive_id()));
            try {
                learninfoDao.add(learninfo);
            } catch (Exception e) {
                return Result.error(500, "" + e);
            }
            List<SInformation> list = new ArrayList<>();
            list.add(sInformation);
            return Result.ok().put("data",list);
        }
    }

    private SInformation dataInjection(SInformation sInformation, GQLStudentInput input , Long userId) {
        //String token = (String) SecurityUtils.getSubject().getPrincipal();
        String token = tokenService.getSystemToken();
        Long schoolId = JwtUtils.getSchoolId(token);

        if(input.getName() != null){

            sInformation.setStudent_name(JSON.toJSONString(input.getName()));
        }
        if (userId != null) {
            sInformation.setUser(usersDao.get(Users.class, userId));
        }
        if(input.getUsed_name() != null){

            sInformation.setUsed_name(JSON.toJSONString(input.getUsed_name()));
        }
        if(input.getIdcard() != null){

            sInformation.setIdcard(input.getIdcard());
        }
        if(input.getNumber() != null){

            sInformation.setStudent_number(input.getNumber());
        }
        if(input.getLearn_code() != null){

            sInformation.setStudent_learncode(input.getLearn_code());
        }
        if(input.getPinyin_name() != null){

            sInformation.setPinyin_name(input.getPinyin_name());
        }
        if(input.getCountry() != null){

            sInformation.setCountry(input.getCountry());
        }
        if(input.getBirthday() != null){

            sInformation.setBirthday(input.getBirthday());
        }
        if(input.getGender() != null){

            sInformation.setSex(input.getGender());
        }
        if (schoolId != null) {
            sInformation.setSchool(schoolsDao.get(Schools.class, schoolId));
        }
        if(input.getPicture() != null){

            sInformation.setPicture(input.getPicture());
        }
        if(input.getNative_place() != null){

            sInformation.setNative_place(JSON.toJSONString(input.getNative_place()));
        }
        if(input.getNation() != null){

            sInformation.setNation(input.getNation());
        }
        if(input.getHkmtb() != null){

            sInformation.setHkmtb(input.getHkmtb());
        }
        if(input.getPolitical() != null){

            sInformation.setPolitical(input.getPolitical());
        }
        if(input.getSpeciality() != null){

            sInformation.setSpeciality(JSON.toJSONString(input.getSpeciality()));
        }
        if(input.getIdentity_ivalidity() != null){

            sInformation.setIdentity_ivalidity(input.getIdentity_ivalidity());
        }
        if(input.getBlood() != null){

            sInformation.setBlood(input.getBlood());
        }
        if(input.getTel_number() != null){

            sInformation.setTel_number(input.getTel_number());
        }
        if(input.getEmail() != null){

            sInformation.setEmail(input.getEmail());
        }
        if(input.getPostal_code() != null){

            sInformation.setPostal_code(input.getPostal_code());
        }
        if(input.getHome_page() != null){

            sInformation.setHome_page(input.getHome_page());
        }
        if(input.getHousehold_register_type() != null){

            sInformation.setHousehold_register_type(input.getHousehold_register_type());
        }
        if(input.getBirth_place() != null){

            sInformation.setBirth_place(JSON.toJSONString(input.getBirth_place()));
        }
        if(input.getPresent_address() != null){

            sInformation.setPresent_address(input.getPresent_address());
        }
        if(input.getCorresponding_address() != null){

            sInformation.setCorresponding_address(input.getCorresponding_address());
        }
        if(input.getFamily_address() != null){

            sInformation.setFamily_address(input.getFamily_address());
        }
        if(input.getHousehold_registed_id() != null){

            sInformation.setHousehold_registed_id(input.getHousehold_registed_id());
        }
        if(input.getHousehold_registed_city_id() != null){

            sInformation.setHousehold_registed_city_id(input.getHousehold_registed_city_id());
        }
        if(input.getHousehold_registed_county_id() != null){

            sInformation.setHousehold_registed_county_id(input.getHousehold_registed_county_id());
        }
        if(input.getCard_type() != null){

            sInformation.setCradkind_id(input.getCard_type());
        }
        if(input.getIs_onlychild() != null){

            sInformation.setIs_onlychild(input.getIs_onlychild());
        }
        if(input.getIs_pre_school_education() != null){

            sInformation.setIs_pre_school_education(input.getIs_pre_school_education());
        }
        if(input.getIs_left_behind_children() != null){

            sInformation.setIs_left_behind_children(input.getIs_left_behind_children());
        }
        if(input.getIs_orphan() != null){

            sInformation.setIs_orphan(input.getIs_orphan());
        }
        if(input.getIs_martyr() != null){

            sInformation.setIs_martyr(input.getIs_martyr());
        }
        if(input.getIs_study_in_class() != null){

            sInformation.setIs_study_in_class(input.getIs_study_in_class());
        }
        if(input.getIs_government_degree() != null){

            sInformation.setIs_government_degree(input.getIs_government_degree());
        }
        if(input.getIs_funding() != null){

            sInformation.setIs_funding(input.getIs_funding());
        }
        if(input.getIs_supplement() != null){

            sInformation.setIs_supplement(input.getIs_supplement());
        }
        if(input.getIs_move_with() != null){

            sInformation.setIs_move_with(input.getIs_move_with());
        }
        if(input.getDisabled_status() != null){

            sInformation.setDisabled_status(input.getDisabled_status());
        }
        if(input.getHealth() != null){

            sInformation.setHealth(input.getHealth());
        }
        return sInformation;
    }
}

